package com.apress.messaging.server;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.apress.messaging.domain.CustomerApi;
import com.apress.messaging.domain.Msg;

import cn.hutool.http.HttpUtil;
import cn.hutool.json.JSONArray;
import cn.hutool.json.JSONUtil;

import java.io.IOException;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import javax.websocket.OnClose;
import javax.websocket.OnError;
import javax.websocket.OnMessage;
import javax.websocket.OnOpen;
import javax.websocket.Session;
import javax.websocket.server.PathParam;
import javax.websocket.server.ServerEndpoint;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.stereotype.Component;
import org.springframework.web.client.RestTemplate;

/**
 * 区域语言en,ja,zh,DE
 * @author Dogness
 *
 */
@ServerEndpoint("/websocket/de/{username}")
@Component
public class WebSocketDEServer {
    private Logger logger = LoggerFactory.getLogger(this.getClass());
    
    @Autowired
    CustomerApi	customerApi;
    
    @Bean	
    public	CustomerApi	getCustomerApi(){
    	return	new	CustomerApi();
    }
    
    /**
     * 在线人数
     */
    public static int onlineNumber = 0;
    /**
     * 以用户的姓名为key，WebSocket为对象保存起来
     */
    private static Map<String, WebSocketDEServer> clients = new ConcurrentHashMap<String, WebSocketDEServer>();
    /**
     * 会话
     */
    private Session session;
    /**
     * 用户名称
     */
    private String username;
    /**
     * 上线调用
     */
    private String online="http://localhost:80/js/status/online";
    /**
     * 下线调用
     */
    private String offline="http://localhost:80/js/status/offline";
	
    @OnOpen
    public void onOpen(@PathParam("username") String username, Session session)
    {
        onlineNumber++;
        HashMap<String, Object> paramMap = new HashMap<>();
        paramMap.put("userName", username);
        String result= HttpUtil.post(online, paramMap);
        logger.info("现在来连接的客户id："+session.getId()+"用户名："+username+"上线结果："+result);
        this.username = username;
        this.session = session;
        logger.info("有新连接加入！ 当前在线人数" + onlineNumber);
        try {
            //messageType 1代表上线 2代表下线 3代表在线名单 4代表普通消息
            JSONObject 	online 	=   new JSONObject();
            JSONObject  header  =   new JSONObject();
            JSONObject  user  =   new JSONObject();
            user.put("username", username);
            header.put("code", 1);
            header.put("message", "user online");
            online.put("header", header);
            online.put("data", username);
            //先给所有人发送通知，说我上线了
            sendMessageAll(online+"",username);
 
            //把自己的信息加入到map当中去
            clients.put(username, this);
            /*//给自己发一条消息：告诉自己现在都有谁在线
            Map<String,Object> map2 = new HashMap<String,Object>();
            map2.put("messageType",3);
            //移除掉自己
            Set<String> set = clients.keySet();
            map2.put("onlineUsers",set);*/
            
            Set<String> set = clients.keySet();
            Iterator<String>	it	=	set.iterator();
            JSONObject  jsa =   new JSONObject();
            JSONArray   PFU =   new JSONArray();
            JSONArray   CSD =   new JSONArray();
            String  key =null;
            //监听上线的类型并分别发送消息
            while (it.hasNext()) {
                    key =   it.next();
                if(key.startsWith("PFU")){
                    PFU.put(key);
                }
                //如果是客服用户则封到“PFU”中
                if(key.startsWith("CSD")){
                    CSD.put(key);
                }
                jsa.put("PFU", PFU);
                jsa.put("CSD", CSD);
            }
            JSONObject onlineUsers =   new JSONObject();
            JSONObject  onlineUsersHeader  =   new JSONObject();
            onlineUsersHeader.put("code", 3);
            onlineUsersHeader.put("message", "all online user");
            onlineUsers.put("header", onlineUsersHeader);
            onlineUsers.put("data", jsa);
            logger.info("\n客服上线获取所有的在线用户列表{}，{}",clients,username);
            
            sendMessageTo(onlineUsers.toJSONString(),username);
            
        }
        catch (IOException e){
            logger.info(username+"上线的时候通知所有人发生了错误");
        }
        
    }
    
    @OnError
    public void onError(Session session, Throwable error) {
        logger.info("服务端发生了错误"+error.getMessage());
        //error.printStackTrace();
    }
    /**
     * 连接关闭
     */
    @OnClose
    public void onClose() {
        onlineNumber--;
        //webSockets.remove(this);
        clients.remove(username);

        JSONObject offLine =   new JSONObject();
        JSONObject  offLineheader  =   new JSONObject();
        try {
            //messageType 1代表上线 2代表下线 3代表在线名单  4代表普通消息
            Map<String,Object> map1 =new HashMap<String,Object>();
            map1.put("messageType",2);
            map1.put("onlineUsers",clients.keySet());
            map1.put("username",username);
            
            //sendMessageAll(JSON.toJSONString(map1),username);
            
            
			HashMap<String, Object> paramMap = new HashMap<>();
            paramMap.put("userName", username);
            String result= HttpUtil.post(offline, paramMap);
            
            cn.hutool.json.JSONObject  jst  =   JSONUtil.parseObj(result);
            cn.hutool.json.JSONObject  headert  =   JSONUtil.parseObj(jst.get("header"));
            if(headert.get("code").equals(1000)){
                offLineheader.put("code", 2);
                offLineheader.put("message", "offline");
                offLine.put("header", offLineheader);
                offLine.put("data", username);
            }else {
                offLineheader.put("code", 2);
                offLineheader.put("message", "offline fail");
                offLine.put("header", offLineheader);
                offLine.put("data", username);
            }
			
            
            sendMessageAll(offLine+"",username);
        }
        catch (IOException e){
            logger.info(username+"下线的时候通知所有人发生了错误");
            try {
            	offLineheader.put("code", 2);
                offLineheader.put("message", e);
                offLine.put("header", offLineheader);
                offLine.put("data", username);
				sendMessageAll(offLine+"",username);
			} catch (IOException e1) {
				// TODO Auto-generated catch block
				e1.printStackTrace();
			}
        }
        logger.info("有连接关闭！ 当前在线人数" + onlineNumber);
    }
 
    @Autowired
    RestTemplateClient	restTemplateClient;
    
	@Value("rootUri")
    private String rootUri;

	
	public	RestTemplate	restTemplate() {
		return	new	RestTemplate();
	}
	
	public	cn.hutool.json.JSONObject	postApi(String	url) {
		cn.hutool.json.JSONObject	result	=	restTemplate().getForObject(url, cn.hutool.json.JSONObject.class);
		return	result;
	}
	
	public	cn.hutool.json.JSONObject	jr(String petUser,String seat) {
		rootUri	=	"http://192.168.0.139:80/js/chatrooms/customer_access";
        //restTemplateClient.setRootUri(rootUri);
		JSONObject  paramMap  =   new JSONObject();
        paramMap.put("petUser", petUser);
        paramMap.put("seat", seat);
        
        String result= HttpUtil.post(rootUri,paramMap);
        return	JSONUtil.parseObj(result);
	}

	

    /**
     * 收到客户端的消息
     *
     * @param message 消息
     * @param session 会话
     */
    @OnMessage
    public void onMessage(String message, Session session)
    {
        try {
            logger.info("\n来自客户端消息：" + message+"客户端的id是："+session.getId());
            JSONObject jsonObject = JSON.parseObject(message);
            
            String fromUser = jsonObject.getString("fromUser");
            String toUser = jsonObject.getString("toUser");
            String	msgType= jsonObject.getString("msgType");
            String	content	=	jsonObject.getString("content");
            
            String	msgId	=	jsonObject.getString("msgId");
            String	userName	=	jsonObject.getString("userName");
            String	sendTime	=	jsonObject.getString("sendTime");
            
            String	petUser	=	jsonObject.getString("petUser");
            String	seat	=	jsonObject.getString("seat");
            logger.info("\npetUser:{}seat{}",petUser,seat);
            if(content.equals("接入用户")) {
            	cn.hutool.json.JSONObject	res	=	
            			jr(jsonObject.getString("petUser"), jsonObject.getString("seat"));
            	String	touser	=	res.getJSONObject("data").getStr("toUser");
            	String	fromUser1	=	res.getJSONObject("data").getStr("fromUser");
            	
            	if(res.getJSONObject("header").getShort("code")==6){
            		logger.info("\n消息体:{}\n接收者：{}",res,touser);
                	//向用户发送接入消息
                	sendMessageTo(res+"",touser);
                	//像客服发送接入成功
                	sendMessageTo(res+"",fromUser1);
            	}else{
            		//像客服发送接入失败
                	sendMessageTo(res+"",fromUser1);
            	}
            	
            }else if(content.equals("人工")){
            	cn.hutool.json.JSONObject	res		=	getCustomerApi().rg(fromUser,toUser,content);
            	logger.info("\n消息体:{}\n接收者：{}",res);
            	Long time = System.currentTimeMillis();
            	Msg msg = new Msg();
                msg.setContent(content);
                msg.setFromUser(fromUser);
                msg.setToUser(toUser);
                msg.setUserName(fromUser);
                msg.setMsgType("Text");

                //msg.setMsgId(Long.parseLong(StringToNumber.letterToNumber(postMessages) + ""));
                msg.setSendTime(time);
                
            	JSONObject 	rgMessage 	=   new JSONObject();
                JSONObject  header  =   new JSONObject();
                JSONObject  user  =   new JSONObject();
                user.put("username", username);
                header.put("code", 5);
                header.put("message", "messages");
                rgMessage.put("header", header);
                rgMessage.put("data", res);
                //向用户返回结果
            	sendMessageTo(rgMessage+"",fromUser);
            	//向客服发送正在请求的用户
            	JSONObject 	cuMessage 	=   new JSONObject();
                JSONObject  cuheader  =   new JSONObject();
                cuheader.put("code", 4);
                cuheader.put("message", "messages");
                cuMessage.put("header", cuheader);
                cuMessage.put("data", msg);
            	logger.info("\n消息体:{}\n接收者：{}",cuMessage,toUser);
            	sendMessageTo(cuMessage+"",toUser);
            }else{
            	//customerApi.sendMsg(message);
            	JSONObject 	jsonMessage 	=   new JSONObject();
                JSONObject  header  =   new JSONObject();
                JSONObject  user  =   new JSONObject();
                user.put("username", username);
                header.put("code", 4);
                header.put("message", "messages");
                jsonMessage.put("header", header);
                jsonMessage.put("data", jsonObject);
                
            	sendMessageTo(jsonMessage+"",toUser);
            }
            
            //如果不是发给所有，那么就发给某一个人
            //messageType 1代表上线 2代表下线 3代表在线名单  4代表普通消息
           /* Map<String,Object> map1 =new HashMap<String,Object>();
            map1.put("messageType",4);
            map1.put("textMessage",textMessage);
            map1.put("fromusername",fromusername);*/
            /*if(toUser.equals("All")){
                //map1.put("tousername","所有人");
                sendMessageAll(message,fromUser);
            }
            else{
                sendMessageTo(message,toUser);
            }*/
        }
        catch (Exception e){
            logger.info("发生了错误了{}", e);
        }
 
    }
 
 
    public void sendMessageTo(String message, String ToUserName) throws IOException {
        for (WebSocketDEServer item : clients.values()) {
            if (item.username.equals(ToUserName) ) {
            	logger.info("\n客服上线获取所有的在线用户列表{}，{}",clients,username);
                item.session.getBasicRemote().sendText(message);
                break;
            }
        }
    }
 
    public void sendMessageAll(String message,String FromUserName) throws IOException {
        for (WebSocketDEServer item : clients.values()) {
            item.session.getAsyncRemote().sendText(message);
        }
    }
 
    public static synchronized int getOnlineCount() {
        return onlineNumber;
    }
}



